package cn.ulc.socket.admin.service.goods.impl;

import cn.hutool.core.convert.Convert;
import cn.ulc.common.constant.PubDataConstant;
import cn.ulc.common.constant.enums.AvailableStatus;
import cn.ulc.common.constant.enums.DeletedStatus;
import cn.ulc.common.exception.PlatformException;
import cn.ulc.socket.admin.common.BaseService;
import cn.ulc.socket.admin.model.dto.goods.GoodsTypeDTO;
import cn.ulc.socket.admin.model.dto.goods.GoodsTypeListDTO;
import cn.ulc.socket.admin.model.param.goods.GoodsTypeSaveParam;
import cn.ulc.socket.admin.service.goods.GoodsTypeServ;
import cn.ulc.store.dao.goods.GoodsDao;
import cn.ulc.store.dao.goods.GoodsTypeDao;
import cn.ulc.store.entity.goods.GoodsType;
import cn.ulc.store.entity.staff.Staff;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class GoodsTypeServImpl extends BaseService implements GoodsTypeServ {

    GoodsTypeDao typeDao;

    GoodsDao goodsDao;

    @Override
    public GoodsTypeListDTO findWaterList(String key, AvailableStatus status) {
        Staff loginUser = getCurrentUser();
        List<GoodsType> typeList = typeDao.findList(PubDataConstant.TYPE_DEPOSIT, key,status,loginUser.getCompanyId());
        return new GoodsTypeListDTO(typeList);
    }
    @Override
    public GoodsTypeListDTO findList(String key, AvailableStatus status) {
        Staff loginUser = getCurrentUser();
        List<GoodsType> typeList = typeDao.findList(PubDataConstant.TYPE_NO_DEPOSIT, key,status,loginUser.getCompanyId());
        return new GoodsTypeListDTO(typeList);
    }

    @Override
    public GoodsTypeListDTO findTreeList() {
        Staff loginUser = getCurrentUser();
        List<GoodsType> list = typeDao.findAllList(loginUser.getCompanyId());
        List<GoodsType> result = new ArrayList<>();
        if(list != null && list.size()>0){
            Map<Long,List<GoodsType>> map = list.parallelStream().collect(Collectors.groupingBy(GoodsType::getParentId));
            result = map.get(0l);
            if(result != null && result.size()>0){
                result.stream().forEach(t->{
                    t.setChildren(map.get(t.getId()));
                });
            }
        }
        return GoodsTypeListDTO.builder().dataList(result).build();
    }

    @Override
    public GoodsTypeDTO findDetail(Long id) {
        long tId = Convert.toLong(id,0l);
        GoodsType entity = typeDao.findOne(tId);
        if(entity==null) throw new PlatformException("未获取到分类信息");
        GoodsType parentType = typeDao.findOne(entity.getParentId());
        return new GoodsTypeDTO(entity, parentType);
    }

    @Override
    public Boolean save(GoodsTypeSaveParam param) {
        GoodsType parentType = null;
        long parentId = Convert.toLong(param.getParentId(),0l);
        if(parentId > 0){
            parentType = typeDao.findOne(param.getParentId());
        }
        GoodsType goodsType = new GoodsType();
        setBaseInfo(goodsType);
        Integer maxSort = typeDao.findMaxSortByParentId(param.getParentId());
        if (maxSort==null) maxSort =0;
        goodsType.setSort(maxSort+1);
        goodsType.setName(param.getName());
        goodsType.setRemark(param.getRemark());
        goodsType.setStatus(AvailableStatus.AVAILABLE);
        goodsType.setIsLeaf(true);
        goodsType.setParentId(parentId);
        goodsType.setType(param.getType());
        goodsType.setLevel(1);
        String nodePath = "/";
        if(parentType!=null) {
            parentType.setIsLeaf(false);
            typeDao.save(parentType);
            goodsType.setLevel(parentType.getLevel()+1);
            nodePath = parentType.getNodeIdPath();
            goodsType.setType(parentType.getType());
        }
        typeDao.save(goodsType);
        goodsType.setNodeIdPath(nodePath+goodsType.getId()+"/");
        typeDao.save(goodsType);
        return true;
    }

    @Override
    public Boolean update(Long id, GoodsTypeSaveParam param) {
        GoodsType goodsType = typeDao.findOne(id);
        if(goodsType==null) throw new PlatformException("未获取到分类信息");
        if(StringUtils.isNotBlank(param.getName())) goodsType.setName(param.getName());
        goodsType.setRemark(param.getRemark());
        setBaseInfo(goodsType);
        typeDao.save(goodsType);
        return true;
    }


    @Override
    @Transactional
    public Boolean changeStatus(Long id, AvailableStatus status) {
        Staff loginUser = getCurrentUser();
        GoodsType goodsType = typeDao.findOne(id);
        if(goodsType == null) throw new PlatformException("未获取到分类信息");
        List<GoodsType> children = typeDao.findList(loginUser.getCompanyId(),goodsType.getId());
        if(children.size() >0){
            for(GoodsType child:children){
                if(status == AvailableStatus.FREEZE){  //禁用
//                    Long i =  goodsDao.findCountByType(goodsType.getId());
//                    if(i >0 )throw new PlatformException("分类已被使用，无法禁用");
                }
                child.setStatus(status);
            }
            typeDao.saveAll(children);
        }
        if(status == AvailableStatus.FREEZE){  //禁用
//            Long i =  goodsDao.findCountByType(goodsType.getId());
//            if(i >0 )throw new PlatformException("分类已被使用，无法禁用");
        }
        goodsType.setStatus(status);
        setBaseInfo(goodsType);
        typeDao.save(goodsType);
        return true;
    }

    @Override
    public Boolean changeSort(String type, Long id1, Long id2) {
        Staff loginUser = getCurrentUser();
        GoodsType goodsType = typeDao.findOne(id1);
        if(goodsType == null) throw new PlatformException("未获取到操作的分类信息");
        if("down".equals(type)){   //下移
            GoodsType goodsType2 = typeDao.findOne(id2);
            List<GoodsType> goodsTypeList = typeDao.findBySort(goodsType.getSort(),goodsType2.getSort(),goodsType.getParentId(),loginUser.getCompanyId());
            for(GoodsType t:goodsTypeList){
                if(t.getId().longValue() != goodsType.getId().longValue()){
                    t.setSort(t.getSort()-1);
                }else{
                    t.setSort(goodsType2.getSort());
                }
            }
            typeDao.saveAll(goodsTypeList);
        }else{  //上移 或 置顶
            Integer begin = 1;
            if("up".equals(type)){   //上移
                GoodsType goodsType2 = typeDao.findOne(id2);
                if(goodsType2==null) throw new PlatformException("操作失败");
                begin = goodsType2.getSort();
            }
            List<GoodsType> goodsTypeList = typeDao.findBySort(begin,goodsType.getSort(),goodsType.getParentId(),loginUser.getCompanyId());
            for(GoodsType t:goodsTypeList){
                if(t.getId().longValue() != goodsType.getId().longValue()){
                    t.setSort(t.getSort()+1);
                }else{
                    t.setSort(begin);
                }
            }
            typeDao.saveAll(goodsTypeList);
        }
        return true;
    }

    @Override
    public Boolean deleted(Long id) {
        long tid = Convert.toLong(id,0l);
        GoodsType entity = typeDao.findOne(tid);
        if(entity != null){
            Long children = typeDao.countByParentId(entity.getId());
            if(children>0) throw new PlatformException("分类存在子分类,不能删除,请处理子分类后尝试");
            Long count = goodsDao.findCountByType(entity.getId());
            if(count> 0) throw new PlatformException("分类存在商品,不能删除,请处理商品后尝试");
            setBaseInfo(entity);
            entity.setDeleted(DeletedStatus.DELETED);
            typeDao.save(entity);
        }
        return true;
    }
}
